package com.sap.jcp.sm.web;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import sun.reflect.ReflectionFactory.GetReflectionFactoryAction;

import com.opensymphony.xwork2.ActionSupport;
import com.sap.jcp.sm.dao.ConfigDAO;
import com.sap.jcp.sm.dao.ConfigDAOImpl;
import com.sap.jcp.sm.dao.ShiftDAO;
import com.sap.jcp.sm.dao.ShiftDAOImpl;
import com.sap.jcp.sm.dao.TrackDAO;
import com.sap.jcp.sm.dao.TrackDAOImpl;
import com.sap.jcp.sm.dao.UserDAO;
import com.sap.jcp.sm.dao.UserDAOImpl;
import com.sap.jcp.sm.dao.UserTimelineDAO;
import com.sap.jcp.sm.dao.UserTimelineDAOImpl;
import com.sap.jcp.sm.domain.Config;
import com.sap.jcp.sm.domain.Shift;
import com.sap.jcp.sm.domain.Track;
import com.sap.jcp.sm.domain.User;
import com.sap.jcp.sm.domain.UserTimeline;
import com.sap.jcp.sm.dto.DailyScheduleDTO;
import com.sap.jcp.sm.dto.ScheduleDTO;
import com.sap.jcp.sm.dto.UserTimelineDTO;
import com.sap.jcp.sm.dto.WeeklyScheduleDTO;
import com.sap.jcp.sm.email.util.ApplicationConfiguraion;
import com.sap.jcp.sm.email.util.EmailManager;
import com.sap.jcp.sm.excel.ExcelExportUtil;
import com.sap.jcp.sm.util.DateUtil;
import com.sap.jcp.sm.util.MappingUtil;
import com.sap.jcp.sm.util.TimelineUtil;

public class ScheduleAction extends ActionSupport implements SessionAware, RequestAware {

	Map sessionMap;
	Map request;
	private static final long serialVersionUID = 1L;
	private UserTimelineDAO userTimelineDAO = new UserTimelineDAOImpl();
	private UserDAO userDAO = new UserDAOImpl();
	private ShiftDAO shiftDAO = new ShiftDAOImpl();
	private TrackDAO trackDAO = new TrackDAOImpl();
	private String weekId;
	ConfigDAO configDAO = new ConfigDAOImpl();


	@Override
	public void setSession(Map<String, Object> map) {
		this.sessionMap = map;
	}

	@Override
	public void setRequest(Map<String, Object> arg0) {
		this.request = arg0;
		
	}


	public String loadLastSchedules() {
		
		List<String> weekIdList = DateUtil.getLastFiveWeekIds(new Date());
		List<UserTimeline> userTimelineList = userTimelineDAO.getLastFiveSchedule(weekIdList);
		Map<String, List<UserTimeline>> mappedUserTimeline = MappingUtil.userTimelineMapperForSchedule(userTimelineList);
		ScheduleDTO scheduleDTO  = new ScheduleDTO();
		
		if (weekIdList != null) {
			Iterator<String> itr = weekIdList.iterator(); 
			Map<String,WeeklyScheduleDTO> weeklyScheduleList = new LinkedHashMap<String, WeeklyScheduleDTO>();
			while (itr.hasNext()) {
				String weekId = itr.next();
				WeeklyScheduleDTO weeklyScheduleDTO = new WeeklyScheduleDTO();
				weeklyScheduleDTO.setWeekId(weekId);
				List<String> weekDateList = DateUtil.getWeekDateList(weekId);
				Map<String,DailyScheduleDTO> dailyScheduleMap = new LinkedHashMap<String, DailyScheduleDTO>();
				if (weekDateList != null) {
					Iterator<String> dayIterator = weekDateList.iterator();
					while (dayIterator.hasNext()) {
						DailyScheduleDTO dailyScheduleDTO = new DailyScheduleDTO();
						String dayCode = dayIterator.next();
						List<UserTimeline> dailyTimelineList = mappedUserTimeline.get(dayCode);
						if (dailyTimelineList == null) {
							dailyTimelineList = new ArrayList<UserTimeline>();
						}
						dailyScheduleDTO.setUserTimelineList(dailyTimelineList);
						dailyScheduleDTO = setShiftMasterNames(dailyScheduleDTO);
						dailyScheduleMap.put(dayCode, dailyScheduleDTO);
					}
				}
				weeklyScheduleDTO.setDailyScheduleList(dailyScheduleMap);
				weeklyScheduleList.put(weekId, weeklyScheduleDTO);
			}
			scheduleDTO.setWeeklyScheduleList(weeklyScheduleList);
		}
		sessionMap.put("scheduleDTO", scheduleDTO);
		return SUCCESS;
	}
	
	
	private DailyScheduleDTO setShiftMasterNames(
			DailyScheduleDTO dailyScheduleDTO) {
		Config config = (Config) sessionMap.get("config");
		if (config == null) {
			config = configDAO.list();
		}
		String shiftMasterTrack = config.getShiftMastersTrack();
		String firstShiftId = config.getFirstShiftId();
		String secondShiftId = config.getSecondShiftId();
		List<UserTimeline> userTimelineList = dailyScheduleDTO.getUserTimelineList();
		if (userTimelineList != null) {
			Iterator<UserTimeline> iter = userTimelineList.iterator();
			while (iter.hasNext()) {
				UserTimeline userTimeline = iter.next();
				if (shiftMasterTrack != null 
						&& shiftMasterTrack.equals(userTimeline.getTrack())) {
					if (firstShiftId != null && firstShiftId.equals(userTimeline.getShift())) {
						if (((Map<String, User>) sessionMap.get("approvedUsers")).get(userTimeline.getUser()) != null) {
							String firstShiftMaster = ((Map<String, User>) sessionMap.get("approvedUsers")).get(userTimeline.getUser()).getName();
							dailyScheduleDTO.setFirstShiftMaster(firstShiftMaster);
						}
					}
					if (secondShiftId != null && secondShiftId.equals(userTimeline.getShift())) {
						if (((Map<String, User>) sessionMap.get("approvedUsers")).get(userTimeline.getUser()) != null ) {
							String secondShiftMaster = ((Map<String, User>) sessionMap.get("approvedUsers")).get(userTimeline.getUser()).getName();
							dailyScheduleDTO.setSecondShiftMaster(secondShiftMaster);
						}
					}
				}
			}
		}
		return dailyScheduleDTO;
	}

	public String loadPublicSchedule() {
		loadBasicSessionValues();
		loadLastSchedules();
		if (sessionMap.get("userTimelineDTO") == null) {
			String weekCode = DateUtil.getWeekCode(new Date());
			UserTimelineDTO userTimelineDTO = new UserTimelineDTO();
			userTimelineDTO = loadUserTimeLineToSession(weekCode, userTimelineDTO);
			sessionMap.put("userTimelineDTO", userTimelineDTO);
		} 
		Config config = configDAO.list();
		sessionMap.put("config", config);
		
		return SUCCESS;
	}
	
	private void loadBasicSessionValues () {
		if (sessionMap.get("approvedUsers") == null) {
			List<User> approvedUserList = userDAO.pendingListUser("Approved");
			sessionMap.put("approvedUsers", MappingUtil.convertUserListToMap(approvedUserList));
		}
		
		if (sessionMap.get("track") == null) {
			List<Track> trackList = trackDAO.listTrack();
			sessionMap.put("track", MappingUtil.convertTrackListToMap(trackList));
		}
		
		if (sessionMap.get("shift") == null) {
			List<Shift> shiftList = shiftDAO.listShift();
			sessionMap.put("shift", MappingUtil.convertShiftListToMap(shiftList));
		}
	}
	
	private UserTimelineDTO loadUserTimeLineToSession(String weekId, UserTimelineDTO userTimelineDTO) {
		List<UserTimeline> userTimelineList = userTimelineDAO.listUserTimeline(weekId);
		Map<String, UserTimeline> userTimelineMap = MappingUtil.userTimelineMapper(userTimelineList);
		Map<String, User> userList = (Map<String, User>) sessionMap.get("approvedUsers");
		userTimelineDTO.setWeekId(weekId);
		userTimelineDTO.setCurrentWeekId(weekId);
		userTimelineDTO.setNextWeekId(DateUtil.getNextWeekId(weekId));
		userTimelineDTO.setPreviousWeekId(DateUtil.getPreviousWeekId(weekId));
		Config config = configDAO.list();
		userTimelineDTO = new TimelineUtil().createUserTimelineDTO(
				userTimelineMap, userList, weekId, userTimelineDTO, (Map<String, Shift>) sessionMap
						.get("shift"), (Map<String, Track>) sessionMap.get("track"), config);
		return userTimelineDTO;
	}

	public String loadScheduleForWeek() {
		String weekId = (String) request.get("weekId");
		loadBasicSessionValues();
		UserTimelineDTO userTimelineDTO = new UserTimelineDTO();
		userTimelineDTO = loadUserTimeLineToSession(weekId, userTimelineDTO);
		sessionMap.put("userTimelineDTOForWeek", userTimelineDTO);
		Config config = configDAO.list();
		sessionMap.put("config", config);
		return SUCCESS;
	}
	
	public String exportScheduleAsExcel() {
		String weekId = (String) request.get("weekId");
		loadBasicSessionValues();
		UserTimelineDTO userTimelineDTO = new UserTimelineDTO();
		userTimelineDTO = loadUserTimeLineToSession(weekId, userTimelineDTO);
		Config config = configDAO.list();
		new ExcelExportUtil().createExcel(userTimelineDTO, realContextPath(), config, 2);
		return SUCCESS;
	}
	
	private String realContextPath() {
		ServletContext context = ServletActionContext.getServletContext();
		return context.getRealPath("/");
	}
	
	public String loadLastFiveWeekList() {
		if (sessionMap.get("lastFiveWeekIdList") == null) {
			List<String> lastFiveWeekIdList = DateUtil.getLastFiveWeekIds(new Date());
			sessionMap.put("lastFiveWeekIdList", lastFiveWeekIdList);
		}
		return SUCCESS;
	}
	
	public String publishSchedule(){
		Map<String, User> userIds = (Map<String, User>) sessionMap.get("approvedUsers");
		List<String> emailIds = new ArrayList<String>();
		if (userIds != null) {
			for(String key : userIds.keySet()) {
				User user = userIds.get(key);
				emailIds.add(user.getEmailId());
			}
		}
		String weekId = (String) request.get("weekId");
		String htmlMessage = ApplicationConfiguraion.getPropertyValue("scheduleEmailBody");
		User sessionUser = (User) sessionMap.get("user");
		htmlMessage = MessageFormat.format(htmlMessage, weekId, sessionUser.getEmailId(), sessionUser.getName());
		String htmlMessageSubject = ApplicationConfiguraion.getPropertyValue("scheduleEmailSubject");
		htmlMessageSubject = MessageFormat.format(htmlMessageSubject, weekId);
		String emailFrom = ApplicationConfiguraion.getPropertyValue("scheduleEmailFrom");
		EmailManager.sendMessage(htmlMessage,htmlMessageSubject, emailIds, emailFrom);
		return SUCCESS;
	}
	/**
	 * @return the weekId
	 */
	public String getWeekId() {
		return weekId;
	}

	/**
	 * @param weekId the weekId to set
	 */
	public void setWeekId(String weekId) {
		this.weekId = weekId;
	}
}
